home *** CD-ROM | disk | FTP | other *** search
/ 130 MIDI Tool Box / 130 MIDI Tool Box.iso / bytemidi / rxint11.a < prev   
Text File  |  1979-12-31  |  13KB  |  376 lines

  1. ;    RXINT:
  2. ;    version 1.1
  3. ;    2/2/86
  4. ;
  5. ;    This is the main receive interrupt.
  6. ;    It is called when the DART receives data.
  7. ;    This version supports carry-over (running) status bytes
  8. ;    as well as a translate table.
  9. ;
  10.  
  11.     DSEG
  12.  
  13. ; These are C's globals
  14. PUBLIC r_segment_
  15. PUBLIC ptr_
  16. PUBLIC end_
  17. PUBLIC destbyte_
  18. PUBLIC clsb_
  19. PUBLIC cmsb_
  20. PUBLIC stop_
  21. PUBLIC LAST_STAT_
  22. PUBLIC C_O_F_           ; status carry-over flag
  23. PUBLIC clk_type_        ; 0=internal,  1=external
  24. PUBLIC counter_dec_
  25. PUBLIC in_filt_            ; the MIDI input filter
  26.                 ; bit:
  27.                 ;   0 = Note on filt
  28.                 ;   1 = Note off filt
  29.                 ;   2 = Prog change filt
  30.                 ;   3 = Channel after-touch
  31.                 ;   4 = Pitch wheel
  32.                 ;   5 = All other controllers
  33.                 ;   6 = Key after-touch
  34.  
  35.     CSEG       ; ALL CODE
  36.  
  37.     PUBLIC rxint_
  38.  
  39. rxint_:
  40.     STI                ; interrupts back on
  41.     PUSH AX
  42.     MOV AL,0B9H         ; shut off counter interrupt
  43.     OUT 021H,AL
  44.     PUSH BX
  45.     PUSH DX
  46.     PUSH ES
  47.     PUSH DS
  48.     MOV AX,0              ; this will be new value for the
  49.                 ; DS so we can access the OLD DS
  50.     MOV DS,AX
  51.     MOV BX,WORD [04FAH]     ; put new DS in BX
  52.     MOV DS,BX               ; put new DS in DS
  53.     MOV AX,r_segment_
  54.     MOV ES,AX               ; set buffer segment
  55.  
  56. sst:
  57.     MOV DX,0FFA2H           ; midi stat
  58.     MOV AL,1                ; rd register 1
  59.     OUT DX,AL
  60.     IN AL,DX                ; RD reg 1
  61.     AND AL,32               ; Rx overrun error?
  62.     JNZ finished            ; if so, than we're REALLY done!
  63. _st:                        ; jumped to by _iret if another char is available
  64.     IN AL,DX                ; read status register
  65.     AND AL,1                ; Rx char?
  66.     JZ _iret                ; if not, return
  67.     MOV DX,0FFA0H           ; MIDI data
  68.     IN AL,DX                ; now let's read it
  69.     MOV DL,AL               ; store in DL for later
  70.     CMP AL,0F8H             ; timing clock?
  71.     JNZ C1                  ; if not, check for stop
  72.     MOV DL,counter_dec_        ; get amount to decrement counter
  73.     MOV DH,0            ; we'll do a word subtract
  74.     MOV AL,clsb_        ; get lsb 
  75.     MOV AH,cmsb_        ; get msb
  76.     SUB AX,DX            ; dcr word
  77.     MOV clsb_,AL        ; store lsb
  78.     MOV cmsb_,AH        ; store msb
  79.     JMP _iret               ; if is, all done
  80.  
  81. C1:
  82.     CMP AL,0FCH             ; MIDI Stop?
  83.     JNZ C4                  ; if not, continue
  84.     MOV BYTE stop_,1        ; else, set stop byte
  85.     JMP _iret               ; and return
  86. C4:
  87.     AND AL,0F0H             ; strip off top 4
  88.     CMP AL,0F0H             ; running status?
  89.     JZ _iret                ; if so, we're done
  90.     MOV BYTE AL,destbyte_    ; get destbyte
  91.     CMP AL,0FFH             ; shall we continue?
  92.     JZ _iret                ; if not, then we're done
  93.     MOV BL,AL               ; keep for later
  94.     AND AL,0F0H             ; strip off top four
  95.     JZ _newmsg              ; first byte of a new message - What a revelation!
  96. contzz:                     ; branch point from carry-over status
  97.     CMP AL,010H             ; Note ON?
  98.     JZ _nton                ; yes?
  99.     CMP AL,020H             ; Note OFF?
  100.     JZ _noff                ; yes?
  101.     CMP AL,070H            ; Poly key pres?
  102.     JZ _keypres
  103.     CMP AL,040H             ; Bender?
  104.     JZ _bender              ; yes?
  105.     CMP AL,050H             ; Control Change?
  106.     JZ _cchan               ; yes?
  107.     CMP AL,060H             ; Channel Velocity?
  108.     JZ _cvel            ; For now, throw away channel velocity
  109.     CMP AL,030H             ; Prog Change?
  110.     JZ _pchan               ; yes?
  111.     JMP _iret            ; This would fall through for FILTed out codes
  112.  
  113.         ; this routine (newmsg) processes the first byte of a given
  114.         ; message, and also decides if it is an important message
  115.  
  116. _newmsg:                ; it's a new message
  117.     MOV AL,DL            ; retrieve
  118.     AND AL,080H
  119.     MOV AL,DL
  120.     MOV BYTE C_O_F_,0        ; no carry-over
  121.     JNZ contxx            ; check for MIDI carry-over stat.
  122.     MOV BYTE AL,LAST_STAT_    ; get previous status byte
  123.     MOV BYTE C_O_F_,0FFH     ; carry-over status
  124. contxx:
  125.     MOV BYTE destbyte_,0    ; this is default in case code isn't
  126.                 ; supported or is filtered out
  127.     MOV CL,in_filt_        ; this is input filter
  128.     AND AL,0F0H             ; strip off channel info.
  129.     MOV LAST_STAT_,AL       ; save new last stat
  130.     CMP AL,090H             ; Note ON?
  131.     JZ _nnon                ; yes?
  132.     CMP AL,080H             ; Note OFF?
  133.     JZ _nnoff               ; yes?
  134.     CMP AL,0A0H            ; Poly key press?
  135.     JZ _nkeypres        ; yes?
  136.     CMP AL,0E0H             ; Pitch Wheel
  137.     JZ _npwch               ; yes?
  138.     CMP AL,0B0H             ; Control Change?
  139.     JZ _ncchan              ; yes?
  140.     CMP AL,0C0H             ; Prog. Chan?
  141.     JZ _npchan              ; yes?
  142.     CMP AL,0D0H             ; Channel Velocity?
  143.     JZ _nchanv            ; yes?
  144.     JMP _iret               ; otherwise, it must be a code we don't support
  145.  
  146. _nnon:                  ; first byte of a note on just came in
  147.     AND CL,1            ; keep note-ons?
  148.     JZ _iret            ; no, then all done.
  149.     CALL _stime            ; store present time
  150.     MOV BYTE ES:[BX],0        ; put 0 at *ptr - I.D. code for note on/off
  151.     MOV BYTE destbyte_,011H    ; note on in dest byte
  152.     JMP _cco                ; check carry-over
  153.  
  154. _nnoff:                 ; first byte of note off just came in
  155.     AND CL,2            ; keep note-offs?
  156.     JZ _iret            ; no, then all done
  157.     CALL _stime             ; same as _nnon (above)
  158.     MOV BYTE ES:[BX],0        ; I.D.
  159.     MOV BYTE destbyte_,021H    ; note off in destbyte
  160.     JMP _cco                ; check carry-over
  161.  
  162. _ncchan:                ; first byte of control change
  163.     AND CL,32            ; keep control changes?
  164.     JZ _iret            ; no
  165.     CALL _stime
  166.     MOV BYTE ES:[BX],0C0H    ; I.D.
  167.     MOV BYTE destbyte_,051H    ; cchan in destbyte
  168.     JMP _cco                ; check carry-over
  169.  
  170. _npchan:                ; 1st byte of program change
  171.     AND CL,4            ; keep prog. changes?
  172.     JZ _iret
  173.     CALL _stime
  174.     MOV BYTE ES:[BX],040H    ; I.D.
  175.     MOV BYTE destbyte_,031H    ; prog chan in destbyte
  176.     JMP _cco                ; check carry-over
  177.  
  178. _nchanv:                ; 1st byte of Channel pressure
  179.     AND CL,8            ; keep channel pressure?
  180.     JZ _iret
  181.     CALL _stime
  182.     MOV BYTE ES:[BX],041H       ; I.D.
  183.     MOV BYTE destbyte_,061H    ; chan vel in dbyte
  184.     JMP _cco            ; check carry-over
  185.  
  186. _nkeypres:        ; 1st byte of Poly. key pres.
  187.     AND CL,64            ; keep poly. key pres?
  188.     JZ _iret
  189.     CALL _stime
  190.     MOV BYTE ES:[BX],060H       ; I.D.
  191.     MOV BYTE destbyte_,071H    ; chan vel in dbyte
  192.     JMP _cco            ; check carry-over
  193.  
  194. _npwch:            ; first byte of pitch wheel change
  195.     AND CL,16            ; keep pitch wheel?
  196.     JZ _iret
  197.     CALL _stime
  198.     MOV BYTE ES:[BX],080H    ; I.D.
  199.     MOV BYTE destbyte_,041H    ; pitch wheel in dbyte
  200.     JMP _cco            ; check carry-over
  201.  
  202. _cco:   ; check carry over flag
  203.     MOV BYTE AL,C_O_F_        ; get carry over flag
  204.     OR AL,AL                ; set flags
  205.     JZ _iret
  206.     MOV BYTE AL,destbyte_
  207.     MOV BL,AL
  208.     AND AL,0F0H
  209.     JMP contzz              ; carry over
  210.  
  211.         ; now for the routines that are called while a message is in
  212.         ; progress:
  213.  
  214. _nton:                      ; note on processing routine
  215.     AND BL,1                ; BL still has destbyte in it
  216.     MOV WORD BX,ptr_        ; get pointer
  217.     JZ _ntonvel             ; must be a 2, so go and save velocity
  218.     OR DL,080H              ; set top bit of note
  219.     ADD BX,3                ; inr pointer to note
  220.     MOV BYTE ES:[BX],DL         ; store it
  221.     INC BYTE destbyte_      ; inr for velocity, which will come in next
  222.     JMP _iret               ; all done
  223. _ntonvel:                   ; must be a velocity byte
  224.     SHR DL,1                ; shift velocity byte one to the right
  225.     OR BYTE ES:[BX],DL          ; OR it in
  226.     MOV BYTE destbyte_,0    ; next byte will be a newmsg
  227.     ADD WORD ptr_,4         ; inr ptr
  228.     JMP _iret            ; all done
  229.  
  230. _noff:                      ; note off processing routine
  231.     AND BL,1                ; BL still has destbyte in it
  232.     MOV WORD BX,ptr_        ; get pointer into buff
  233.     JZ _ntoffvel            ; if destbyte=2, then it must be a velocity
  234.     ADD BX,3                ; inr to where we'll store the note
  235.     MOV BYTE ES:[BX],DL        ; store note; top bit should already be 0
  236.     INC BYTE destbyte_      ; inr destbyte for velocity
  237.     JMP _iret               ; all done
  238. _ntoffvel:                  ; must be a velocity byte
  239.     SHR DL,1            ; shift DL logically right 1
  240.     OR BYTE ES:[BX],DL        ; OR it in
  241.     MOV BYTE destbyte_,0    ; next byte will be a newmsg
  242.     ADD WORD ptr_,4         ; now _ptr points to the next message spot
  243.     JMP _iret               ; all done
  244.  
  245. _pchan:                     ; program change (new program)
  246.     MOV WORD BX,ptr_        ; get pointer; no need to check byte number
  247.                             ; because only two bytes are transmitted
  248.     ADD BX,3                ; this is where we'll store the new prog. #
  249.     MOV BYTE ES:[BX],DL         ; store data
  250.     MOV BYTE destbyte_,0    ; reset to newmsg
  251.     ADD WORD ptr_,4         ; inr to pstn. of next massage
  252.     JMP _iret            ; all done
  253.  
  254. _bender:                    ; store bender data
  255.     AND BL,1                ; first data byte?
  256.     JZ _bmsb                ; if not, than go and store the MSB
  257.     INC BYTE destbyte_      ; inr for next pass
  258.     JMP _iret               ; all done
  259. _bmsb:                      ; store MSB of bender
  260.     SHR DL,1                ; shift DL down 1
  261.     MOV WORD BX,ptr_        ; get ptr
  262.     OR BYTE ES:[BX],DL        ; OR in top 6 of MSB of bender
  263.     ADD WORD ptr_,3         ; inr pointer to next message
  264.     MOV BYTE destbyte_,0    ; next message will newmsg
  265.     JMP _iret            ; all done
  266.  
  267.  
  268. _cchan:                     ; control change
  269.     AND BL,1                ; control #?
  270.     MOV WORD BX,ptr_        ; get ptr_
  271.     JNZ _cnum               ; if input is control #, then save it
  272.     ADD BX,4                ; this is where we'll store the control value
  273.     MOV BYTE ES:[BX],DL         ; store control value
  274.     MOV BYTE destbyte_,0    ; next byte will newmsg
  275.     ADD WORD ptr_,5         ; inr to next message location
  276.     JMP _iret               ; all done
  277. _cnum:                      ; number
  278.     ADD BX,3                ; address of control number
  279.     MOV BYTE ES:[BX],DL     ; store control number
  280.     INC BYTE destbyte_      ; next byte will be control value
  281.     JMP _iret               ; all done
  282.  
  283. _cvel:                      ; channel velocity
  284.     MOV WORD BX,ptr_        ; load BX w/pointer
  285.     MOV BYTE ES:[BX+3],DL    ; store velocity
  286.     ADD WORD ptr_,4        ; inr to next message pstn.
  287.     MOV BYTE destbyte_,0    ; next byte will be new msg
  288.     JMP _iret               ; all done
  289.  
  290. _keypres:            ; poly. key pressure
  291.     AND BL,1             ; amount?
  292.     MOV WORD BX,ptr_
  293.     JZ _storepres        ; store key pressure
  294.     ADD BX,3            ; this is where to store the note num.
  295.     MOV BYTE ES:[BX],DL        ; store it
  296.     INC BYTE destbyte_        ; next byte will be val.
  297.     JMP _iret
  298. _storepres:            ; store key pressure
  299.     SHR DL,1
  300.     SHR DL,1            ; shift DL right 2 (/4)
  301.     OR ES:[BX],DL        ; OR it in
  302.     MOV BYTE destbyte_,0    ; next byte new message
  303.     JMP _iret            ; all done
  304.  
  305.  
  306. _stime:                     ; routine to read the PIT and store the results
  307.                             ; in the buffer
  308.     PUSH DX                 ; preserve data
  309.     MOV WORD BX,ptr_        ; get pointer
  310.     MOV AL,clk_type_        ; get clk type (0=int)
  311.     OR AL,AL            ; set flags
  312.     JNZ ext_clk            ; is clk_type=ext_clk??
  313.     MOV AL,64               ; counter latching operation
  314.     MOV DX,0FFA7H           ; counter stat
  315.     OUT DX,AL               ; out to PIT
  316.     NOP                     ; stall for time
  317.     NOP
  318.     MOV DX,0FFA5H           ; counter 2
  319.     IN AL,DX                ; read _clsb
  320.     MOV BYTE ES:[BX+1],AL    ; store in buffer
  321.     NOP
  322.     NOP
  323.     IN AL,DX                ; read _cmsb
  324.     MOV BYTE ES:[BX+2],AL
  325.     POP DX                  ; restore data
  326.     RET
  327.  
  328. ext_clk:        ; timing clock from MIDI
  329.     MOV DL,clsb_
  330.     MOV DH,cmsb_        ; get MSB & LSB
  331.     MOV BYTE ES:[BX+1],DL
  332.     MOV BYTE ES:[BX+2],DH    ; store MSB & LSB
  333.     POP DX            ; restore DX
  334.     RET                ; all done
  335.  
  336. _eoi:                ; send EOI to PIC
  337.     PUSH AX                 ; we'll be using this
  338.     MOV AL,020H             ; EOI
  339.     OUT 020H,AL             ; EOI
  340.     POP AX                  ; restore AX
  341.     RET                     ; all done
  342.  
  343. _iret1:                ; execute EOI and then return
  344.     CALL _eoi
  345.  
  346. finished:                   ; Rx overrun error
  347.     MOV BYTE stop_,0FFH     ; CRITICAL ERROR!!!
  348.     JMP f2
  349.  
  350. _iret:                      ; all done routine
  351.     MOV DX,0FFA2H           ; DART status reg
  352.     IN AL,DX
  353.     AND AL,1                ; RxD? (THIS WILL HAVE TO BE CHANGED TO CHECK
  354.                             ;       FOR EXTERNAL STAT. ALSO)
  355.     JNZ  sst                ; if so, than go to top of routine
  356. f2:                ; C equivalent:
  357.                 ;     if(end > ptr)
  358.                 ;        goto okay;
  359.                 ;     else
  360.                 ;           stop=1;
  361. ;   MOV BX,ptr_
  362. ;   MOV DX,end_
  363. ;   CMP DX,BX
  364. ;   JG f3
  365. ;   MOV BYTE stop_,1    ; Woaaaah!! Stop Everything!! - We're out of memory
  366. f3:
  367.     mov al,0b8h
  368.     out 021h,al
  369.     POP DS
  370.     POP ES
  371.     POP DX
  372.     POP BX
  373.     POP AX                  ; retrieve registers
  374.     call _eoi
  375.     IRET                    ; ALL DONE!!!!!!!
  376.